import React, { Component } from 'react'
import PubSub from 'pubsub-js'
import Header from './components/Header/Header'
import List from './components/List/List'
import Footer from './components/Footer/Footer'
import context from './context'
import './App.css'

export default class App extends Component {
  // 状态提升: 将Header,Footer等组件需要使用的状态数据定义在他们的父级组件中
  state = {
    // 要考虑用户第一次打开任务列表,没有数据的时候,我们初始化一个空数组
    list: JSON.parse(localStorage.getItem('list')) || [],
    editId: undefined, // 用来控制哪个任务展示编辑的文本框. 如果是undefined则表示所有任务都不显示编辑的文本框.如果是一个具体的id,则对应有相同id的任务展示编辑文本框
  }

  // app中定义一个函数,这个函数传递给Header组件
  addTodo = (todoName) => {
    // 创建一个任务对象
    const newTodo = {
      id: Date.now(),
      todoName,
      isDone: false,
    }
    // 将新任务对象添加到list中
    this.state.list.push(newTodo)
    // 调用setState让组件更新
    this.setState({
      list: this.state.list,
    })
  }

  // app中定义一个函数,这个函数传递给Item组件,未来用于修改数据的isDone
  updateTodo = (id) => {
    // id就是需要修改isDone的那个数据的id

    this.state.list.forEach((item) => {
      if (item.id === id) {
        item.isDone = !item.isDone
      }
    })

    this.setState({
      list: this.state.list,
    })
  }
  // 删除一条任务
  delTodo = (id) => {
    // newList是一个数组,里面存储了没有被过滤掉的数据
    const newList = this.state.list.filter((item) => {
      return item.id !== id
    })

    this.setState({
      list: newList,
    })
  }

  // 全选按钮的功能
  allDone = (target) => {
    // 将list中所有数据的isDone改成target
    this.state.list.forEach((item) => {
      item.isDone = target
    })

    this.setState({
      list: this.state.list,
    })
  }

  // 删除所有已完成数据
  clearDone = () => {
    const newList = this.state.list.filter((item) => !item.isDone)
    this.setState({
      list: newList,
    })
  }

  // 修改editId的函数
  setEditId = (id) => {
    this.setState({
      editId: id,
    })
  }

  // 修改任务名
  editTodoName = (id, newTN) => {
    this.state.list.forEach((item) => {
      if (item.id === id) {
        item.todoName = newTN
      }
    })
    this.setState({
      list: this.state.list,
      // editId: undefined,
    })
  }
  render() {
    return (
      <context.Provider value={this.state.editId}>
        <div className="todo-container">
          <div className="todo-wrap">
            <Header></Header>
            {this.state.list.length ? (
              <div>
                <List
                  list={this.state.list}
                  updateTodo={this.updateTodo}
                  delTodo={this.delTodo}
                  setEditId={this.setEditId}
                  editTodoName={this.editTodoName}
                ></List>
                <Footer
                  list={this.state.list}
                  allDone={this.allDone}
                  clearDone={this.clearDone}
                ></Footer>
              </div>
            ) : (
              <h1>恭喜您,没有任务!</h1>
            )}
          </div>
        </div>
      </context.Provider>
    )
  }

  componentDidUpdate() {
    // 由于每一次修改list数据,都应该将最新的list数据存储到localStorage中.所以为了省事,就把存储localStorage的代码写在render中
    // 因为每次修改数据,都会调用setState,就会触发render.所以写在render中更简单
    localStorage.setItem('list', JSON.stringify(this.state.list))
  }

  componentDidMount() {
    this.addId = PubSub.subscribe('add', (topic, todoName) => {
      this.addTodo(todoName)
    })
  }

  componentWillUnmount() {
    PubSub.unsubscribe(this.addId)
  }
}
